{% extends "layout.html" %}

<!-- Simplified view of Rhasspy profile -->

{% block body %}
<div class="form-group mb-3">
    <div class="form-row">
        <div class="col-auto">
            <button onclick="saveProfile()" class="btn btn-primary" title="Save all settings and restart Rhasspy">Save Settings</button>
        </div>
        <div class="col-auto">
            <a href="{{ url_prefix }}/api/backup-profile" class="btn btn-success" title="Download zip file with profile files">Backup Profile</a>
        </div>
    </div>
</div>

<!-- siteId -->
<div class="form-group">
    <div class="form-row">
        <div class="col-auto">
            <label for="mqtt-siteid" class="col-form-label">siteId:</label>
        </div>
        <div class="col-6">
            <input id="mqtt-siteid" type="text" class="form-control" x-model="profile.mqtt.site_id" placeholder="default">
        </div>
    </div>
</div>
<!-- End siteId -->

<!-- MQTT -->
<div class="card" id="mqtt">
    <div class="card-header bg-dark" id="headingMqtt">
        <i class="fas fa-inverse fa-network-wired"></i>
        <button class="btn" x-bind:class="{ 'btn-outline-light': !profile.mqtt.enabled, 'btn-success': profile.mqtt.enabled }" data-toggle="collapse" data-target="#mqtt-collapse" aria-expanded="true" aria-controls="mqtt-collapse" :disabled="!profile.mqtt.enabled">
            <i class="fas fa-sort-down"></i>MQTT
        </button>

        <select class="ml-2" x-model="profile.mqtt.enabled">
            <option value="">Internal</option>
            <option value="true">External</option>
        </select>

        <span class="fa-stack ml-2" x-show="profile.mqtt.enabled != initialSystems.mqtt">
            <i class="fas fa-circle fa-stack-2x text-danger"></i>
            <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
        </span>
    </div>
    <div id="mqtt-collapse" class="collapse hide" aria-labelledby="headingMqtt" data-parent="#accordion">
        <div class="card-body">
            <div class="form-group">
                <div class="form-row">
                    <label for="mqtt-host" class="col-form-label">Host</label>
                    <div class="col-sm-auto">
                        <input id="mqtt-host" type="text" class="form-control" x-model="profile.mqtt.host" :disabled="!profile.mqtt.enabled">
                    </div>
                </div>
            </div>
            <div class="form-group">
                <div class="form-row">
                    <label for="mqtt-port" class="col-form-label">Port</label>
                    <div class="col-sm-auto">
                        <input id="mqtt-port" type="text" class="form-control" x-model="profile.mqtt.port" :disabled="!profile.mqtt.enabled">
                    </div>
                </div>
            </div>
            <div class="form-group">
                <div class="form-row">
                    <label for="mqtt-username" class="col-form-label">Username</label>
                    <div class="col-sm-auto">
                        <input id="mqtt-username" type="text" class="form-control" x-model="profile.mqtt.username" :disabled="!profile.mqtt.enabled">
                    </div>
                </div>
            </div>
            <div class="form-group">
                <div class="form-row">
                    <label for="mqtt-password" class="col-form-label">Password</label>
                    <div class="col-sm-auto">
                        <input id="mqtt-password" type="password" class="form-control" x-model="profile.mqtt.password" :disabled="!profile.mqtt.enabled">
                    </div>
                </div>
            </div>
            <hr>
            <div class="form-group">
                <div class="form-row">
                    <div class="col-sm-auto">
                        <input id="mqtt-tls-enabled" type="checkbox" x-model="profile.mqtt.tls.enabled" :disabled="!profile.mqtt.enabled">
                        <label for="mqtt-tls-enabled" class="col-form-label">TLS over MQTT (encryption)</label>
                    </div>
                </div>
                <div class="form-row">
                    <div class="col">
                        <a target="_blank" href="https://www.eclipse.org/paho/clients/python/docs/#tls-set" title="Paho MQTT tls_set documentation">Documentation</a>
                    </div>
                </div>
            </div>
            <template x-if="profile.mqtt.tls.enabled">
                <div class="form-group">
                    <div class="form-row">
                        <label for="mqtt-tls-ca_certs" class="col-form-label">ca_certs</label>
                        <div class="col">
                            <input id="mqtt-tls-ca_certs" type="text" class="form-control" v-model="profile.mqtt.tls.ca_certs" :disabled="!profile.mqtt.enabled">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="mqtt-tls-cert_reqs" class="col-form-label">cert_reqs</label>
                        <div class="col-sm-auto">
                            <select id="mqtt-tls-cert_reqs" v-model="profile.mqtt.tls.cert_reqs" :disabled="!profile.mqtt.enabled">
                                <option value="CERT_REQUIRED" default>CERT_REQUIRED</option>
                                <option value="CERT_OPTIONAL">CERT_OPTIONAL</option>
                                <option value="CERT_NONE">CERT_NONE</option>
                            </select>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="mqtt-tls-certfile" class="col-form-label">certfile</label>
                        <div class="col">
                            <input id="mqtt-tls-certfile" type="text" class="form-control" v-model="profile.mqtt.tls.certfile" :disabled="!profile.mqtt.enabled">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="mqtt-tls-ciphers" class="col-form-label">ciphers</label>
                        <div class="col">
                            <input id="mqtt-tls-ciphers" type="text" placeholder="default ciphers" class="form-control" v-model="profile.mqtt.tls.ciphers" :disabled="!profile.mqtt.enabled">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="mqtt-tls-keyfile" class="col-form-label">keyfile</label>
                        <div class="col">
                            <input id="mqtt-tls-keyfile" type="text" class="form-control" v-model="profile.mqtt.tls.keyfile" :disabled="!profile.mqtt.enabled">
                        </div>
                    </div>
                </div>
            </template>
        </div>
    </div>
</div>
<!-- End MQTT -->

<!-- Audio Recording -->
<div class="card" id="microphone">
    <div class="card-header bg-dark" id="headingMicrophone">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-microphone"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.microphone.system == 'dummy', 'btn-success': profile.microphone.system != 'dummy' }" data-toggle="collapse" data-target="#microphone-collapse" aria-expanded="true" aria-controls="microphone-collapse" :disabled="profile.microphone.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Audio Recording
            </button>
            <select class="ml-2" x-model="profile.microphone.system">
                <option value="dummy">Disabled</option>
                <option value="pyaudio">PyAudio{% if profile.get("microphone.recommended") == "pyaudio" %} (Recommended){% endif %}</option>
                <option value="arecord">arecord{% if profile.get("microphone.recommended") == "arecord" %} (Recommended){% endif %}</option>
                <option value="command">Local Command</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.microphone.system != initialSystems.microphone">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
        </h5>
    </div>
    <div id="microphone-collapse" class="collapse hide" aria-labelledby="headingMicrophone" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.microphone.system != initialSystems.microphone">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- PyAudio -->
            <div x-show="profile.microphone.system == 'pyaudio'" :disabled="initialSystems.microphone != 'pyaudio'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Streams microphone data from a <a href="https://people.csail.mit.edu/hubert/pyaudio/">PyAudio</a> device (<a target="_blank" href="{{ url_prefix }}/docs/audio-input/#pyaudio">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="microphone-pyaudio-device">Device:</label>
                        </div>
                        <div class="col">
                            <input id="microphone-pyaudio-device" x-model="profile.microphone.pyaudio.device" type="text" class="form-control" placeholder="default">
                        </div>
                    </div>
                    <div class="form-row mt-2">
                        <div class="col">
                            <select id="microphone-pyaudio-devices" x-model="profile.microphone.pyaudio.device" class="form-control">
                                <option value="" selected>Default Device</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshInputDevices('pyaudio')" class="btn btn-primary form-control">Refresh</button>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="testInputDevices('pyaudio')" class="btn btn-secondary form-control">Test</button>
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-pyaudio-udp-audio-port" class="col-form-label">UDP Audio (Output)</label>
                        <div class="col">
                            <input id="microphone-pyaudio-udp-audio-host" type="text" class="form-control" placeholder="host" x-model="profile.microphone.pyaudio.udp_audio_host" :disabled="profile.microphone.system != 'pyaudio'">
                        </div>
                        <div class="col">
                            <input id="microphone-pyaudio-udp-audio-port" type="text" class="form-control" placeholder="port" x-model="profile.microphone.pyaudio.udp_audio_port" :disabled="profile.microphone.system != 'pyaudio'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-pyaudio-siteid" class="col-form-label">Output siteId</label>
                        <div class="col">
                            <input id="microphone-pyaudio-siteid" type="text" class="form-control" x-model="profile.microphone.pyaudio.siteId" :disabled="profile.microphone.system != 'pyaudio'">
                        </div>
                        <div class="col-auto text-muted">
                            (output to different siteId)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End PyAudio -->

            <!-- arecord -->
            <div x-show="profile.microphone.system == 'arecord'" :disabled="initialSystems.microphone != 'arecord'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Starts an <tt>arecord</tt> process locally and reads audio data from its standard out (<a target="_blank" href="{{ url_prefix }}/docs/audio-input/#alsa">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="microphone-arecord-device">Device:</label>
                        </div>
                        <div class="col">
                            <input id="microphone-arecord-device" x-model="profile.microphone.arecord.device" type="text" class="form-control" placeholder="default">
                        </div>
                    </div>
                    <div class="form-row mt-2">
                        <div class="col">
                            <select id="microphone-arecord-devices" x-model="profile.microphone.arecord.device" class="form-control">
                                <option value="" selected>Default Device</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshInputDevices('arecord')" class="btn btn-primary form-control">Refresh</button>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="testInputDevices('arecord')" class="btn btn-secondary form-control">Test</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-arecord-udp-audio-port" class="col-form-label">UDP Audio (Output)</label>
                        <div class="col">
                            <input id="microphone-arecord-udp-audio-host" type="text" class="form-control" placeholder="host" x-model="profile.microphone.arecord.udp_audio_host" :disabled="profile.microphone.system != 'arecord'">
                        </div>
                        <div class="col">
                            <input id="microphone-arecord-udp-audio-port" type="text" class="form-control" placeholder="port" x-model="profile.microphone.arecord.udp_audio_port" :disabled="profile.microphone.system != 'arecord'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-arecord-siteid" class="col-form-label">Output siteId</label>
                        <div class="col">
                            <input id="microphone-arecord-siteid" type="text" class="form-control" x-model="profile.microphone.arecord.siteId" :disabled="profile.microphone.system != 'arecord'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End arecord -->

            <!-- Command -->
            <div x-show="profile.microphone.system == 'command'" :disabled="initialSystems.microphone != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls an external program to record raw audio (<a target="_blank" href="{{ url_prefix }}/docs/audio-input/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-record-program" class="col-form-label">Record Program</label>
                        <div class="col">
                            <input id="microphone-record-program" type="text" class="form-control" x-model="profile.microphone.command.record_program" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-record-arguments" class="col-form-label">Record Arguments</label>
                        <div class="col">
                            <input id="microphone-record-arguments" type="text" class="form-control" x-model="profile.microphone.command.record_arguments" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-sample-rate" class="col-form-label">Sample Rate</label>
                        <div class="col">
                            <input id="microphone-sample-rate" type="text" class="form-control" x-model="profile.microphone.command.sample_rate" :disabled="profile.microphone.system != 'command'">
                        </div>
                        <div class="col-auto text-muted">
                            (Hertz)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-sample-width" class="col-form-label">Sample Width</label>
                        <div class="col">
                            <input id="microphone-sample-width" type="text" class="form-control" x-model="profile.microphone.command.sample_width" :disabled="profile.microphone.system != 'command'">
                        </div>
                        <div class="col-auto text-muted">
                            (bytes)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-channels" class="col-form-label">Channels</label>
                        <div class="col">
                            <input id="microphone-channels" type="text" class="form-control" x-model="profile.microphone.command.channels" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-list-program" class="col-form-label">List Program</label>
                        <div class="col">
                            <input id="microphone-list-program" type="text" class="form-control" x-model="profile.microphone.command.list_program" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-list-arguments" class="col-form-label">List Arguments</label>
                        <div class="col">
                            <input id="microphone-list-arguments" type="text" class="form-control" x-model="profile.microphone.command.list_arguments" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-test-program" class="col-form-label">Test Program</label>
                        <div class="col">
                            <input id="microphone-test-program" type="text" class="form-control" x-model="profile.microphone.command.test_program" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-test-arguments" class="col-form-label">Test Arguments</label>
                        <div class="col">
                            <input id="microphone-test-arguments" type="text" class="form-control" x-model="profile.microphone.command.test_arguments" :disabled="profile.microphone.system != 'command'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-command-udp-audio-port" class="col-form-label">UDP Audio Port</label>
                        <div class="col">
                            <input id="microphone-command-udp-audio-port" type="text" class="form-control" x-model="profile.microphone.command.udp_audio_port" :disabled="profile.microphone.system != 'command'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="microphone-command-siteid" class="col-form-label">Output siteId</label>
                        <div class="col">
                            <input id="microphone-command-siteid" type="text" class="form-control" x-model="profile.microphone.command.siteId" :disabled="profile.microphone.system != 'command'">
                        </div>
                        <div class="col-auto text-muted">
                            (output to different siteId)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Hermes -->
            <div x-show="profile.microphone.system == 'hermes'" :disabled="initialSystems.microphone != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects audio frames from a custom external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> (<a target="_blank" href="{{ url_prefix }}/docs/services/#audio-input">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

            <div x-show="profile.microphone.system != 'dummy'">
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <input type="checkbox" id="toggle-audio-statistics" onclick="toggleAudioStatistics()">
                        <label for="toggle-audio-statistics" class="col-form-label">Audio Statistics</label>
                    </div>
                    <div class="form-row">
                        <p class="alert alert-info">
                            <strong>Note:</strong> statistics will not work if UDP audio is enabled
                        </p>
                    </div>
                    <div class="form-row">
                        <div id="audio-statistics-connecting" class="alert alert-warning">Connecting to websocket...</div>
                    </div>
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="audio-current-energy" class="col-form-label">Current Energy:</label>
                        </div>
                        <div class="col">
                            <input type="text" id="audio-current-energy" readonly>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="audio-max-energy" class="col-form-label">Max Energy:</label>
                        </div>
                        <div class="col">
                            <input type="text" id="audio-max-energy" readonly>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="audio-min-energy" class="col-form-label">Min Energy:</label>
                        </div>
                        <div class="col">
                            <input type="text" id="audio-min-energy" readonly>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="audio-ratio-energy" class="col-form-label">Max/Current Ratio:</label>
                        </div>
                        <div class="col">
                            <input type="text" id="audio-ratio-energy" readonly>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- End Audio Recording -->

<!-- Wake Word -->
<div class="card" id="wake">
    <div class="card-header bg-dark" id="headingWake">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-exclamation-circle"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.wake.system == 'dummy', 'btn-success': profile.wake.system != 'dummy', 'btn-warning': !isWakeCompatible() }" data-toggle="collapse" data-target="#wake-collapse" aria-expanded="true" aria-controls="wake-collapse" :disabled="profile.wake.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Wake Word
            </button>
            <select class="ml-2" x-model="profile.wake.system">
                <option value="dummy">Disabled</option>
                <option value="raven">Rhasspy Raven{% if profile.get("wake.recommended") == "raven" %} (Recommended){% endif %}</option>
                <option value="porcupine">Porcupine{% if profile.get("wake.recommended") == "porcupine" %} (Recommended){% endif %}</option>
                <option value="snowboy">Snowboy{% if profile.get("wake.recommended") == "snowboy" %} (Recommended){% endif %}</option>
                <option value="precise">Mycroft Precise{% if profile.get("wake.recommended") == "precise" %} (Recommended){% endif %}</option>
                <option value="pocketsphinx">Pocketsphinx{% if profile.get("wake.recommended") == "pocketsphinx" %} (Recommended){% elif not profile.get("speech_to_text.pocketsphinx.compatible") %} (Incompatible){% endif %}</option>
                <option value="command">Local Command</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.wake.system != initialSystems.wake">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
            <i title="Wake system is not compatible with this profile" class="fas fa-exclamation-triangle text-warning ml-2" x-show="!isWakeCompatible()"></i>
        </h5>
    </div>
    <div id="wake-collapse" class="collapse hide" aria-labelledby="headingWake" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.wake.system != initialSystems.wake">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- Pocketsphinx -->
            <div x-show="profile.wake.system == 'pocketsphinx'" :disabled="initialSystems.wake != 'pocketsphinx'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Listens for a keyphrase using <a href="https://github.com/cmusphinx/pocketsphinx">pocketsphinx</a> (<a target="_blank" href="{{ url_prefix }}/docs/wake-word/#pocketsphinx">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-pocketsphinx-keyphrase" class="col-form-label">Wake Keyphrase</label>
                        <div class="col-sm-auto">
                            <input id="wake-pocketsphinx-keyphrase" type="text" class="form-control" x-model="profile.wake.pocketsphinx.keyphrase" :disabled="profile.wake.system != 'pocketsphinx'">
                        </div>
                        <div class="col text-muted">
                            3-4 syllables recommended
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-pocketsphinx-sensitivity" class="col-form-label">Sensitivity</label>
                        <div class="col-sm-auto">
                            <input id="wake-pocketsphinx-sensitivity" type="number" min="0" max="1" step="0.1" class="form-control" x-model="pocketsphinxWakeSensitivity" :disabled="profile.wake.system != 'pocketsphinx'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-pocketsphinx-udp-audio" class="col-form-label">UDP Audio (Input)</label>
                        <div class="col">
                            <input id="wake-pocketsphinx-udp-audio" type="text" class="form-control" placeholder="host1:port1:siteId1,host2:port2:siteId2" x-model="profile.wake.pocketsphinx.udp_audio" :disabled="profile.wake.system != 'pocketsphinx'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Pocketsphinx -->

            <!-- Snowboy -->
            <div x-show="profile.wake.system == 'snowboy'" :disabled="initialSystems.wake != 'snowboy'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Listens for one or more wake words with <a href="https://snowboy.kitt.ai">snowboy</a> (<a target="_blank" href="{{ url_prefix }}/docs/wake-word/#snowboy">Documentation</a>)
                        </p>
                    </div>
                    <div class="form-row">
                        <div class="col text-muted">
                            Put models in <tt>{{ profile_dir / "snowboy" }}</tt> </li>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="wake-snowboy-model">Model:</label>
                        </div>
                        <div class="col">
                            <input id="wake-snowboy-model" x-model="profile.wake.snowboy.model" type="text" class="form-control">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="wake-snowboy-hotwords">Available Models:</label>
                        </div>
                        <div class="col">
                            <select id="wake-snowboy-hotwords" x-model="profile.wake.snowboy.model" class="form-control">
                                <option value="" disabled>Select model</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshHotwords('snowboy')" class="btn btn-primary form-control" title="Refresh snowboy models">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-snowboy-sensitivity" class="col-form-label">Sensitivity</label>
                        <div class="col-sm-auto">
                            <input id="wake-snowboy-sensitivity" type="text" class="form-control" x-model="profile.wake.snowboy.sensitivity" :disabled="profile.wake.system != 'snowboy'"> <span class="text-muted">(comma-separated)</span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <input type="checkbox" id="wake-snowboy-applyfrontend" x-model="profile.wake.snowboy.apply_frontend" :disabled="profile.wake.system != 'snowboy'">
                        <label for="wake-snowboy-applyfrontend" class="col-form-label">Apply Frontend (<a href="https://github.com/kitt-ai/snowboy#pretrained-universal-models" title="Parameters for pre-trained models">more info</a>)</label>
                    </div>
                </div>
                <div class="form-group">
                    <p>
                        See <a target="_blank" href="{{ url_prefix }}/docs/wake-word/#snowboy">documentation</a> for how to use multiple wake words.
                    </p>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-snowboy-udp-audio" class="col-form-label">UDP Audio (Input)</label>
                        <div class="col">
                            <input id="wake-snowboy-udp-audio" type="text" class="form-control" placeholder="host1:port1:siteId1,host2:port2:siteId2" x-model="profile.wake.snowboy.udp_audio" :disabled="profile.wake.system != 'snowboy'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Snowboy -->

            <!-- Porcupine -->
            <div x-show="profile.wake.system == 'porcupine'" :disabled="initialSystems.wake != 'porcupine'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Listens for a wake word with <a href="https://github.com/Picovoice/Porcupine">porcupine</a> (<a target="_blank" href="{{ url_prefix }}/docs/wake-word/#porcupine">Documentation</a>)
                        </p>
                    </div>
                    <div class="form-row">
                        <div class="col text-muted">
                            Put models in <tt>{{ profile_dir / "porcupine" }}</tt> </li>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="wake-porcupine-keyword-file">Keyword File:</label>
                        </div>
                        <div class="col">
                            <input id="wake-porcupine-keyword-file" x-model="profile.wake.porcupine.keyword_path" type="text" class="form-control">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="wake-porcupine-hotwords">Available Keywords:</label>
                        </div>
                        <div class="col">
                            <select id="wake-porcupine-hotwords" x-model="profile.wake.porcupine.keyword_path" class="form-control">
                                <option value="" disabled>Select keyword</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshHotwords('porcupine')" class="btn btn-primary form-control" title="Refresh porcupine keywords">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-porcupine-sensitivity" class="col-form-label">Sensitivity</label>
                        <div class="col-sm-auto">
                            <input id="wake-porcupine-sensitivity" type="text" class="form-control" x-model="profile.wake.porcupine.sensitivity" :disabled="profile.wake.system != 'porcupine'"> <span class="text-muted">(comma-separated)</span>
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-porcupine-udp-audio" class="col-form-label">UDP Audio (Input)</label>
                        <div class="col">
                            <input id="wake-porcupine-udp-audio" type="text" class="form-control" placeholder="host1:port1:siteId1,host2:port2:siteId2" x-model="profile.wake.porcupine.udp_audio" :disabled="profile.wake.system != 'porcupine'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Porcupine -->

            <!-- Mycroft Precise -->
            <div x-show="profile.wake.system == 'precise'" :disabled="initialSystems.wake != 'precise'">
                {% if not has_cpu_avx: %}
                <div class="form-group">
                    <div class="form-row">
                        <div class="alert alert-warning">
                            <i class="fas fa-exclamation-triangle mr-2"></i>
                            Precise requires <a href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions">AVX instructions</a>, which your CPU does not support.
                        </div>
                    </div>
                </div>
                {% endif %}
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Listens for a wake word with <a href="https://github.com/MycroftAI/mycroft-precise">Mycroft Precise</a> (<a target="_blank" href="{{ url_prefix }}/docs/wake-word/#precise">Documentation</a>)
                        </p>
                    </div>
                    <div class="form-row">
                        <div class="col text-muted">
                            Put models in <tt>{{ profile_dir / "precise" }}</tt> </li>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="wake-precise-model-file">Model File:</label>
                        </div>
                        <div class="col">
                            <input id="wake-precise-model-file" x-model="profile.wake.precise.model" type="text" class="form-control">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="wake-precise-hotwords">Available Models:</label>
                        </div>
                        <div class="col">
                            <select id="wake-precise-hotwords" x-model="profile.wake.precise.model" class="form-control">
                                <option value="" disabled>Select model</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshHotwords('precise')" class="btn btn-primary form-control" title="Refresh Mycroft Precise models">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-precise-sensitivity" class="col-form-label">Sensitivity</label>
                        <div class="col-sm-auto">
                            <input id="wake-precise-sensitivity" type="text" class="form-control" x-model="profile.wake.precise.sensitivity" :disabled="profile.wake.system != 'precise'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-precise-trigger-level" class="col-form-label">Trigger Level</label>
                        <div class="col-sm-auto">
                            <input id="wake-precise-trigger-level" type="text" class="form-control" x-model="profile.wake.precise.trigger_level" :disabled="profile.wake.system != 'precise'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-precise-udp-audio" class="col-form-label">UDP Audio (Input)</label>
                        <div class="col">
                            <input id="wake-precise-udp-audio" type="text" class="form-control" placeholder="host1:port1:siteId1,host2:port2:siteId2" x-model="profile.wake.precise.udp_audio" :disabled="profile.wake.system != 'precise'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Mycroft Precise -->


            <!-- Rhasspy Raven -->
            <div x-show="profile.wake.system == 'raven'" :disabled="initialSystems.wake != 'raven'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Listens for a wake word with <a href="https://github.com/rhasspy/rhasspy-wake-raven">Raven</a> (<a target="_blank" href="{{ url_prefix }}/docs/wake-word/#raven">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        {% set raven_template_path = maybe_read_path(profile, "wake.raven.template_dir", "raven") %}
                        {% set raven_template_dir = profile.get("wake.raven.template_dir", "raven") %}
                        <ul>
                            <li>Template Directory: <tt>{{ raven_template_path }}</tt> </li>
                        </ul>
                    </div>
                </div>

                <div class="form-group">
                    <div class="form-row">
                        <div class="col">
                            <button id="wake-raven-restart-required" style="display: none;" onclick="saveProfile(true)" class="btn btn-danger mb-3" title="Save all settings and restart Rhasspy">
                                <i class="fas fa-power-off fa-inverse mr-2"></i>
                                Save and Restart Required
                            </button>
                        </div>
                    </div>
                    <div class="form-row">
                        <table class="table table-striped">
                            <thead>
                                <th style="width: 10%;">Enabled</th>
                                <th style="width: 30%;">Keyword</th>
                                <th>Example 1</th>
                                <th>Example 2</th>
                                <th>Example 3</th>
                                <th>&nbsp;</th>
                            </thead>
                            <tbody>
                                {% set keywords = profile.get("wake.raven.keywords", {}) %}

                                <!-- Add keywords that aren't in profile yet -->
                                {% if raven_template_path.is_dir():  %}
                                    {% for keyword_dir in raven_template_path.iterdir():  %}
                                        {% if keyword_dir.name not in keywords: %}
                                            {{ keywords.update({keyword_dir.name: { "enabled": True }}) }}
                                        {% endif %}
                                    {% endfor %}
                                {% endif %}

                                {% for keyword_name, keyword_settings in keywords.items(): %}
                                {% set keyword_dir = raven_template_path / keyword_name %}
                                {% if keyword_dir.is_dir(): %}
                                <tr>
                                    <td>
                                        <input type="checkbox" x-model="profile.wake.raven.keywords['{{ keyword_name }}'].enabled">
                                    </td>

                                    <td>{{ keyword_name }}</td>
                                    {% for i in range(3): %}
                                    <td>
                                        <button class="btn btn-info" title="Re-record wake word example" onclick="ravenRecord(this, '{{ keyword_name }}', {{ i }}, '{{ raven_template_dir }}', true)">
                                            <i class="fas fa-check" style="display: none;"></i>
                                            Re-record
                                        </button>
                                        <button class="btn btn-success" title="Play wake word example" onclick="playRavenExample('{{ keyword_name }}', {{ i }}, '{{ raven_template_path }}')">
                                            <i class="fas fa-play"></i>
                                        </button>
                                    </td>
                                    {% endfor %}
                                    <td>
                                        <button class="btn btn-danger" title="Delete {{ keyword_name }}" onclick="deleteHotword('{{ keyword_name }}')">
                                            <i class="fas fa-inverse fa-trash mr-2"></i>
                                            Delete
                                        </button>
                                    </td>
                                </tr>
                                {% endif %}
                                {% endfor %}

                                <!-- New Keyword -->
                                <tr>
                                    <td>
                                        &nbsp;
                                    </td>
                                    <td>
                                        <input id="wake-raven-keyword-name" type="text" class="form-control" placeholder="new keyword name" :disabled="profile.wake.system != 'raven'">
                                    </td>
                                    {% for i in range(3): %}
                                    <td>
                                        <button class="btn btn-success" title="Record wake word example" onclick="ravenRecord(this, '', {{ i }}, '{{ raven_template_dir }}')">
                                            <i class="fas fa-check" style="display: none;"></i>
                                            Record
                                        </button>
                                        <button class="btn btn-success" title="Play wake word example" onclick="playRavenExample('', {{ i }}, '{{ raven_template_path }}')">
                                            <i class="fas fa-play"></i>
                                        </button>
                                    </td>
                                    {% endfor %}
                                    <td>
                                        <button class="btn btn-primary" title="Save new keyword" onclick="saveRavenKeyword()">
                                            <i class="fas fa-inverse fa-save mr-2"></i>
                                            Save
                                        </button>
                                    </td>
                                </tr>
                                <!-- End New Keyword -->
                            </tbody>
                        </table>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <h5>Default Settings</h5>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="wake-raven-probability-threshold" class="col-form-label">Probability Threshold</label>
                        </div>
                        <div class="col-sm-auto">
                            <input id="wake-raven-probability-threshold" class="form-control" x-model="profile.wake.raven.probability_threshold" :disabled="profile.wake.system != 'raven'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="raven-average-templates" class="col-form-label">Average Templates</label>
                        </div>
                        <div class="col">
                            <input type="checkbox" id="raven-average-templates" class="form-control" x-model="profile.wake.raven.average_templates">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="wake-raven-minimum-matches" class="col-form-label">Minimum Matches</label>
                        </div>
                        <div class="col">
                            <input id="wake-raven-minimum-matches" type="text" class="form-control" x-model="profile.wake.raven.minimum_matches" :disabled="profile.wake.system != 'raven'">
                        </div>
                    </div>
                </div>
                <div class="form-row">
                    <div class="col-auto">
                        <label for="raven-vad-sensitivity" class="col-form-label">VAD Sensitivity:</label>
                    </div>
                    <div class="col">
                        <input id="raven-vad-sensitivity" type="text" class="form-control" x-model="profile.wake.raven.vad_sensitivity">
                    </div>
                    <div class="col-auto text-muted">
                        (1-3)
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-raven-udp-audio" class="col-form-label">UDP Audio (Input)</label>
                        <div class="col">
                            <input id="wake-raven-udp-audio" type="text" class="form-control" placeholder="host1:port1:siteId1,host2:port2:siteId2" x-model="profile.wake.raven.udp_audio" :disabled="profile.wake.system != 'raven'">
                        </div>
                        <div class="col-auto text-muted">
                            (outside ASR listening)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Command -->
            <div x-show="profile.wake.system == 'command'" :disabled="initialSystems.wake != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls a custom external program and wakes up when the program exits (<a target="_blank" href="{{ url_prefix }}/docs/wake-word/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-program" class="col-form-label">Program</label>
                        <div class="col">
                            <input id="wake-program" type="text" class="form-control" x-model="profile.wake.command.program" :disabled="profile.wake.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="wake-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="wake-arguments" type="text" class="form-control" x-model="profile.wake.command.arguments" :disabled="profile.wake.system != 'command'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Hermes -->
            <div x-show="profile.wake.system == 'hermes'" :disabled="initialSystems.wake != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects hotword detections from an external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> (<a target="_blank" href="{{ url_prefix }}/docs/services/#wake-word">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

            <!-- Satellite siteIds -->
            <div x-show="!['dummy', 'hermes'].includes(profile.wake.system)">
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="wake-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="wake-satellite-siteids" type="text" class="form-control" x-model="profile.wake.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- End Wake Word -->

<!-- Speech to Text -->
<div class="card" id="speech">
    <div class="card-header bg-dark" id="headingSpeech">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-phone-volume"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.speech_to_text.system == 'dummy', 'btn-success': profile.speech_to_text.system != 'dummy', 'btn-warning': !isSpeechCompatible() }" data-toggle="collapse" data-target="#speech-collapse" aria-expanded="true" aria-controls="collapseSpeech" :disabled="profile.speech_to_text.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Speech to Text
            </button>
            <select class="ml-2" x-model="profile.speech_to_text.system">
                <option value="dummy">Disabled</option>
                <option value="pocketsphinx">Pocketsphinx{% if profile.get("speech_to_text.recommended") == "pocketsphinx" %} (Recommended){% elif not profile.get("speech_to_text.pocketsphinx.compatible") %} (Incompatible){% endif %}</option>
                <option value="kaldi">Kaldi{% if profile.get("speech_to_text.recommended") == "kaldi" %} (Recommended){% elif not profile.get("speech_to_text.kaldi.compatible") %} (Incompatible){% endif %}</option>
                <option value="deepspeech">Mozilla DeepSpeech{% if profile.get("speech_to_text.recommended") == "deepspeech" %} (Recommended){% elif not profile.get("speech_to_text.deepspeech.compatible") %} (Incompatible){% endif %}</option>
                <option value="vosk">Vosk{% if profile.get("speech_to_text.recommended") == "vosk" %} (Recommended){% elif not profile.get("speech_to_text.vosk.compatible") %} (Incompatible){% endif %}</option>
                <option value="remote">Remote HTTP</option>
                <option value="command">Local Command</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.speech_to_text.system != initialSystems.stt">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
            <i title="Speech system is not compatible with this profile" class="fas fa-exclamation-triangle text-warning ml-2" x-show="!isSpeechCompatible()"></i>
        </h5>
    </div>
    <div id="speech-collapse" class="collapse hide" aria-labelledby="headingSpeech" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.speech_to_text.system != initialSystems.stt">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- Pocketsphinx -->
            <div x-show="profile.speech_to_text.system == 'pocketsphinx'" :disabled="initialSystems.stt != 'pocketsphinx'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Does speech recognition with <a href="https://github.com/cmusphinx/pocketsphinx">CMU's pocketsphinx</a>. Less accurate, but supports many languages (<a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#pocketsphinx">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Acoustic Model: <tt>{{ maybe_read_path(profile, "speech_to_text.pocketsphinx.acoustic_model") }}</tt> </li>
                            <li>Dictionary: <tt>{{ maybe_read_path(profile, "speech_to_text.pocketsphinx.dictionary") }}</tt> </li>
                            <li>Language Model: <tt>{{ maybe_read_path(profile, "speech_to_text.pocketsphinx.language_model") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col">
                            <input type="checkbox" id="pocketsphinx-open" x-model="profile.speech_to_text.pocketsphinx.open_transcription">
                            <label for="pocketsphinx-open" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#open-transcription">
                                    Open transcription mode
                                </a>
                                (no custom voice commands)
                            </label>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="pocketsphinx-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="pocketsphinx-min-confidence" type="text" class="form-control" x-model="profile.speech_to_text.pocketsphinx.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Base Dictionary: <tt>{{ maybe_read_path(profile, "speech_to_text.pocketsphinx.base_dictionary") }}</tt> </li>
                            <li>Base Language Model: <tt>{{ maybe_read_path(profile, "speech_to_text.pocketsphinx.base_language_model") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="pocketsphinx-mix-weight" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/training/#language-model-mixing">
                                    Mixed Language Model Weight
                                </a>
                            </label>
                        </div>
                        <div class="col">
                            <input id="pocketsphinx-mix-weight" type="text" class="form-control" x-model="profile.speech_to_text.pocketsphinx.mix_weight">
                        </div>
                        <div class="col-auto">
                            <span class="text-muted">(0-1, 0 to disable)</span>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Base Language Model FST: <tt>{{ maybe_read_path(profile, "speech_to_text.pocketsphinx.base_language_model_fst") }}</tt> </li>
                        </ul>
                    </div>
                </div>
            </div>
            <!-- End Pocketsphinx -->

            <!-- Kaldi -->
            <div x-show="profile.speech_to_text.system == 'kaldi'" :disabled="initialSystems.stt != 'kaldi'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Does speech recognition with <a href="https://kaldi-asr.org">Kaldi</a>. Fast and accurate for trained sentences (<a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#kaldi">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Model Root: <tt>{{ maybe_read_path(profile, "speech_to_text.kaldi.model_dir") }}</tt> </li>
                            <li>Graph Directory: <tt>&lt;model_root&gt;/{{ profile.get("speech_to_text.kaldi.graph") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-language-model-type" class="col-form-label">
                                Language Model Type:
                            </label>
                        </div>
                        <div class="col">
                            <select id="kaldi-language-model-type" class="form-control" x-model="profile.speech_to_text.kaldi.language_model_type">
                                <option value="arpa">ARPA</option>
                                <option value="text_fst">Text FST</option>
                            </select>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col">
                            <input type="checkbox" id="kaldi-allow-unknown-words" x-model="profile.speech_to_text.kaldi.allow_unknown_words" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                            <label for="kaldi-allow-unknown-words" class="col-form-label">
                                Replace
                                <a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#unknown-words">
                                    unknown words
                                </a>
                                with
                                <input id="kaldi-unknown-token" type="text" x-model="profile.speech_to_text.kaldi.unknown_token" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                            </label>
                        </div>
                        <div class="col-auto text-muted">
                            (re-train required)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-unknown-words-probability" class="col-form-label">Unknown Words Probability:</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-unknown-words-probability" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.unknown_words_probability" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, default: 1e-5)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-silence-probability" class="col-form-label">Silence Probability:</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-silence-probability" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.silence_probability" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, default: 0.5)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-max-unknown-words" class="col-form-label">Maximum Unknown Words</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-max-unknown-words" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.max_unknown_words" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                        </div>
                        <div class="col-auto text-muted">
                            (words in longest possible misspoken sentence)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-max-frequent-words" class="col-form-label">Maximum Frequent Words</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-max-frequent-words" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.max_frequent_words" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                        </div>
                        <div class="col-auto text-muted">
                            (used to catch misspoken words)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-cancel-word" class="col-form-label">Cancel Word:</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-cancel-word" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.cancel_word" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                        </div>
                        <div class="col-auto text-muted">
                            (word used to cancel an intent at any time)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-cancel-probability" class="col-form-label">Cancel Probability:</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-cancel-probability" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.cancel_probability" :disabled="profile.speech_to_text.kaldi.language_model_type != 'text_fst'">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, default: 1e-2)
                        </div>
                    </div>
                </div>

                <div class="form-group">
                    <div class="form-row">
                        <div class="col">
                            <input type="checkbox" id="kaldi-open" x-model="profile.speech_to_text.kaldi.open_transcription">
                            <label for="kaldi-open" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#open-transcription">
                                    Open transcription mode
                                </a>
                                (no custom voice commands)
                            </label>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="kaldi-min-confidence" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Base Dictionary: <tt>{{ maybe_read_path(profile, "speech_to_text.kaldi.base_dictionary") }}</tt> </li>
                            <li>Base Graph Directory: <tt>{{ maybe_read_path(profile, "speech_to_text.kaldi.base_graph") }}</tt> </li>
                            <li>Base Language Model: <tt>{{ maybe_read_path(profile, "speech_to_text.kaldi.base_language_model") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="kaldi-mix-weight" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/training/#language-model-mixing">
                                    Mixed Language Model Weight
                                </a>
                            </label>
                        </div>
                        <div class="col">
                            <input id="kaldi-mix-weight" type="text" class="form-control" x-model="profile.speech_to_text.kaldi.mix_weight">
                        </div>
                        <div class="col-auto">
                            <span class="text-muted">(0-1, 0 to disable)</span>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Base Language Model FST: <tt>{{ maybe_read_path(profile, "speech_to_text.kaldi.base_language_model_fst") }}</tt> </li>
                        </ul>
                    </div>
                </div>
            </div>
            <!-- End Kaldi -->

            <!-- DeepSpeech -->
            <div x-show="profile.speech_to_text.system == 'deepspeech'" :disabled="initialSystems.stt != 'deepspeech'">
                {% if not has_cpu_avx: %}
                <div class="form-group">
                    <div class="form-row">
                        <div class="alert alert-warning">
                            <i class="fas fa-exclamation-triangle mr-2"></i>
                            DeepSpeech requires <a href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions">AVX instructions</a>, which your CPU does not support.
                        </div>
                    </div>
                </div>
                {% endif %}
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Does speech recognition with <a href="https://github.com/mozilla/DeepSpeech">Mozilla's DeepSpeech</a> version 0.9.
                            Slower on some hardware, but often more accurate (<a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#deepspeech">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Acoustic Model: <tt>{{ maybe_read_path(profile, "speech_to_text.deepspeech.acoustic_model") }}</tt> </li>
                            <li>Language Model: <tt>{{ maybe_read_path(profile, "speech_to_text.deepspeech.language_model") }}</tt> </li>
                            <li>Scorer: <tt>{{ maybe_read_path(profile, "speech_to_text.deepspeech.scorer") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col">
                            <input type="checkbox" id="deepspeech-open" x-model="profile.speech_to_text.deepspeech.open_transcription">
                            <label for="deepspeech-open" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#open-transcription">
                                    Open transcription mode
                                </a>
                                (no custom voice commands)
                            </label>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="deepspeech-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="deepspeech-min-confidence" type="text" class="form-control" x-model="profile.speech_to_text.deepspeech.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Base Language Model: <tt>{{ maybe_read_path(profile, "speech_to_text.deepspeech.base_language_model") }}</tt> </li>
                            <li>Base Scorer: <tt>{{ maybe_read_path(profile, "speech_to_text.deepspeech.base_scorer") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="deepspeech-mix-weight" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/training/#language-model-mixing">
                                    Mixed Language Model Weight
                                </a>
                            </label>
                        </div>
                        <div class="col">
                            <input id="deepspeech-mix-weight" type="text" class="form-control" x-model="profile.speech_to_text.deepspeech.mix_weight">
                        </div>
                        <div class="col-auto">
                            <span class="text-muted">(0-1, 0 to disable)</span>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Base Language Model FST: <tt>{{ maybe_read_path(profile, "speech_to_text.kaldi.base_language_model_fst") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="stt-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="stt-satellite-siteids" type="text" class="form-control" x-model="profile.speech_to_text.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End DeepSpeech -->

            <!-- Vosk -->
            <div x-show="profile.speech_to_text.system == 'vosk'" :disabled="initialSystems.stt != 'vosk'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Does speech recognition with <a href="https://alphacephei.com/vosk/">Vosk</a>. Fast and accurate for open transcription (<a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#vosk">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Model Root: <tt>{{ maybe_read_path(profile, "speech_to_text.vosk.model_dir") }}</tt> </li>
                            <li>Words JSON: <tt>{{ maybe_read_path(profile, "speech_to_text.vosk.words_json") }}</tt> </li>
                        </ul>
                    </div>
                </div>

                <div class="form-group">
                    <div class="form-row">
                        <div class="col">
                            <input type="checkbox" id="vosk-open" x-model="profile.speech_to_text.vosk.open_transcription">
                            <label for="vosk-open" class="col-form-label">
                                <a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#open-transcription">
                                    Open transcription mode
                                </a>
                                (no custom voice commands)
                            </label>
                        </div>
                        <div class="col-auto">
                            <span class="fa-stack">
                                <i class="fas fa-circle fa-stack-2x text-info"></i>
                                <i class="fas fa-download fa-stack-1x fa-inverse" title="Requires extra download"></i>
                            </span>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="vosk-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="vosk-min-confidence" type="text" class="form-control" x-model="profile.speech_to_text.vosk.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Vosk -->

            <!-- Remote -->
            <div x-show="profile.speech_to_text.system == 'remote'" :disabled="initialSystems.stt != 'remote'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            POSTs WAV audio to a remote HTTP endpoint, expecting a plain text transcription back (<a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#remote">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="stt-url" class="col-form-label">Speech to Text URL</label>
                        <div class="col">
                            <input id="stt-url" type="text" class="form-control" x-model="profile.speech_to_text.remote.url" :disabled="profile.speech_to_text.system != 'remote'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col text-muted">
                            Example: http://localhost:12101/{{ url_prefix }}/api/speech-to-text
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="speech-remote-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="speech-remote-min-confidence" type="text" class="form-control" x-model="profile.speech_to_text.remote.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="stt-train-url" class="col-form-label">Training URL</label>
                        <div class="col">
                            <input id="stt-train-url" type="text" class="form-control" x-model="profile.training.speech_to_text.remote.url" :disabled="profile.speech_to_text.system != 'remote'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Remote -->

            <!-- Command -->
            <div x-show="profile.speech_to_text.system == 'command'" :disabled="initialSystems.stt != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls an external program with WAV audio on standard input and expects a text transcription on standard output (<a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="stt-program" class="col-form-label">Program</label>
                        <div class="col">
                            <input id="stt-program" type="text" class="form-control" x-model="profile.speech_to_text.command.program" :disabled="profile.speech_to_text.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="stt-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="stt-arguments" type="text" class="form-control" x-model="profile.speech_to_text.command.arguments" :disabled="profile.speech_to_text.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="speech-command-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="speech-command-min-confidence" type="text" class="form-control" x-model="profile.speech_to_text.command.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>

                <hr>

                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="stt-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="stt-satellite-siteids" type="text" class="form-control" x-model="profile.speech_to_text.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Hermes -->
            <div x-show="profile.speech_to_text.system == 'hermes'" :disabled="initialSystems.stt != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects an external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> to do speech to text (<a target="_blank" href="{{ url_prefix }}/docs/services/#speech-to-text">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

            <div x-show="!['dummy', 'hermes'].includes(profile.speech_to_text.system)">
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="stt-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="stt-satellite-siteids" type="text" class="form-control" x-model="profile.speech_to_text.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row mb-3">
                        <h5>Voice Command Settings</h5>
                    </div>
                    <div class="form-row mb-3">
                        <a target="_blank" href="{{ url_prefix }}/docs/speech-to-text/#silence-detection">Documentation</a>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-silence-method" class="col-form-label">Silence Method</label>
                        </div>
                        <div class="col">
                            <select id="webrtcvad-silence-method" class="form-control" x-model="profile.command.webrtcvad.silence_method">
                                <option value="vad_only">VAD</option>
                                <option value="current_only">Current Energy</option>
                                <option value="ratio_only">Max/Current Energy Ratio</option>
                                <option value="vad_and_current">VAD + Current Energy</option>
                                <option value="vad_and_ratio">VAD + Max/Current Energy Ratio</option>
                                <option value="all">VAD + Current Energy + Max/Current Energy Ratio</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-vad-mode" class="col-form-label">VAD Sensitivity:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-vad-mode" type="text" class="form-control" x-model="profile.command.webrtcvad.vad_mode">
                        </div>
                        <div class="col-auto text-muted">
                            (1-3)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-current-energy-threshold" class="col-form-label">Current Energy Threshold:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-current-energy-threshold" type="text" class="form-control" x-model="profile.command.webrtcvad.current_energy_threshold">
                        </div>
                        <div class="col-auto text-muted">
                            (audio above threshold is speech)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-max-current-energy-ratio-threshold" class="col-form-label">Max/Current Energy Ratio Threshold</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-max-current-energy-ratio-threshold" type="text" class="form-control" x-model="profile.command.webrtcvad.max_current_energy_ratio_threshold">
                        </div>
                        <div class="col-auto text-muted">
                            (audio below threshold is speech)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-max-energy" class="col-form-label">Max Energy:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-max-energy" type="text" class="form-control" x-model="profile.command.webrtcvad.max_energy">
                        </div>
                        <div class="col-auto text-muted">
                            (set from audio input if no value)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-skip-sec" class="col-form-label">Skip Before:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-skip-sec" type="text" class="form-control" x-model="profile.command.webrtcvad.skip_sec">
                        </div>
                        <div class="col-auto text-muted">
                            (seconds)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-min-sec" class="col-form-label">Minimum Duration:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-min-sec" type="text" class="form-control" x-model="profile.command.webrtcvad.min_sec">
                        </div>
                        <div class="col-auto text-muted">
                            (seconds)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-max-sec" class="col-form-label">Maximum Duration:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-max-sec" type="text" class="form-control" x-model="profile.command.webrtcvad.max_sec">
                        </div>
                        <div class="col-auto text-muted">
                            (seconds or empty)
                        </div>
                    </div>
                    <div class="form-row  mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-speech-sec" class="col-form-label">Speech Before:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-speech-sec" type="text" class="form-control" x-model="profile.command.webrtcvad.speech_sec">
                        </div>
                        <div class="col-auto text-muted">
                            (seconds)
                        </div>
                    </div>
                    <div class="form-row mb-3">
                        <div class="col-auto">
                            <label for="webrtcvad-silence-sec" class="col-form-label">Silence After:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-silence-sec" type="text" class="form-control" x-model="profile.command.webrtcvad.silence_sec">
                        </div>
                        <div class="col-auto text-muted">
                            (seconds)
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="webrtcvad-silence-sec" class="col-form-label">Record Before:</label>
                        </div>
                        <div class="col">
                            <input id="webrtcvad-before-sec" type="text" class="form-control" x-model="profile.command.webrtcvad.before_sec">
                        </div>
                        <div class="col-auto text-muted">
                            (seconds)
                        </div>
                    </div>
                </div>
            </div>

        </div>
    </div>
</div>
<!-- End Speech to Text -->

<!-- Intent Recognition -->
<div class="card" id="intent">
    <div class="card-header bg-dark" id="headingIntent">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-comment"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.intent.system == 'dummy', 'btn-success': profile.intent.system != 'dummy' }" data-toggle="collapse" data-target="#intent-collapse" aria-expanded="true" aria-controls="intent-collapse" :disabled="profile.intent.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Intent Recognition
            </button>
            <select class="ml-2" x-model="profile.intent.system">
                <option value="dummy">Disabled</option>
                <option value="fsticuffs">Fsticuffs{% if profile.get("intent.recommended") == "fsticuffs" %} (Recommended){% endif %}</option>
                <option value="fuzzywuzzy">Fuzzywuzzy{% if profile.get("intent.recommended") == "fuzzywuzzy" %} (Recommended){% endif %}</option>
                <option value="rasa">Rasa NLU</option>
                <!-- <option value="snips">Snips NLU</option> -->
                <option value="remote">Remote HTTP</option>
                <option value="command">Local Command</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.intent.system != initialSystems.intent">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
        </h5>
    </div>
    <div id="intent-collapse" class="collapse hide" aria-labelledby="headingIntent" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.intent.system != initialSystems.intent">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- Fsticuffs -->
            <div x-show="profile.intent.system == 'fsticuffs'" :disabled="initialSystems.intent != 'fsticuffs'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses <a href="https://github.com/rhasspy/rhasspy-nlu">rhasspy-nlu</a> to recognize only the <a href="sentences">sentences Rhasspy was trained on</a> (<a target="_blank" href="{{ url_prefix }}/docs/intent-recognition/#fsticuffs">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Intent Graph: <tt>{{ maybe_read_path(profile, "intent.fsticuffs.intent_graph") }}</tt> </li>
                            <li>Stop Words: <tt>{{ maybe_read_path(profile, "intent.adapt.stop_words") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <input type="checkbox" id="fsticuffs-fuzzy" x-model="profile.intent.fsticuffs.fuzzy" :disabled="profile.intent.system != 'fsticuffs'">

                        <label for="fsticuffs-fuzzy" class="col-form-label">Fuzzy text matching</label>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="fsticuffs-failure-token" class="col-form-label">Failure Token:</label>
                        </div>
                        <div class="col">
                            <input id="fsticuffs-failure-token" type="text" class="form-control" x-model="profile.intent.fsticuffs.failure_token">
                        </div>
                        <div class="col-auto text-muted">
                            (input word that always causes recognition failure)
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="intent-satellite-siteids" type="text" class="form-control" x-model="profile.intent.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Fsticuffs -->

            <!-- Fuzzywuzzy -->
            <div x-show="profile.intent.system == 'fuzzywuzzy'" :disabled="initialSystems.intent != 'fuzzywuzzy'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Finds the closest matching intent using <a href="https://github.com/maxbachmann/rapidfuzz">rapidfuzz library</a> (<a target="_blank" href="{{ url_prefix }}/docs/intent-recognition/#fuzzywuzzy">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-fuzzywuzzy-min-confidence" class="col-form-label">Minimum Confidence:</label>
                        </div>
                        <div class="col">
                            <input id="intent-fuzzywuzzy-min-confidence" type="text" class="form-control" x-model="profile.intent.fuzzywuzzy.min_confidence">
                        </div>
                        <div class="col-auto text-muted">
                            (0-1, 1 is most strict)
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="intent-satellite-siteids" type="text" class="form-control" x-model="profile.intent.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Fuzzywuzzy -->

            <!-- Rasa NLU -->
            <div x-show="profile.intent.system == 'rasa'" :disabled="initialSystems.intent != 'rasa'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            <a target="_blank" href="{{ url_prefix }}/docs/intent-recognition/#rasanlu">Documentation</a>
                        </p>
                    </div>
                    <div class="form-row">
                        <p class="alert alert-info">
                            <strong>Note:</strong> requires an external service (<a href="https://rasa.com/docs/rasa/installation">installation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-rasa-url" class="col-form-label">Server URL:</label>
                        </div>
                        <div class="col">
                            <input id="intent-rasa-url" type="text" class="form-control" x-model="profile.intent.rasa.url">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col text-muted">
                            Example: http://localhost:5005
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Examples File: <tt>{{ maybe_read_path(profile, "intent.rasa.examples_markdown") }}</tt> </li>
                            <li>Intent Graph: <tt>{{ maybe_read_path(profile, "intent.fsticuffs.intent_graph") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-rasa-project" class="col-form-label">Project Name:</label>
                        </div>
                        <div class="col">
                            <input id="intent-rasa-project" type="text" class="form-control" x-model="profile.intent.rasa.project_name">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-rasa-config" class="col-form-label">YAML Config:</label>
                        </div>
                        <div class="col">
                            <input id="intent-rasa-config" type="text" class="form-control" x-model="profile.intent.rasa.config_yaml" placeholder="(auto-generated)">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="intent-satellite-siteids" type="text" class="form-control" x-model="profile.intent.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Rasa NLU -->

            <!-- Snips NLU -->
            <div x-show="profile.intent.system == 'snips'" :disabled="initialSystems.intent != 'snips'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses <a href="https://github.com/snipsco/snips-nlu">Snips NLU</a> to flexibly recognize sentences (<a target="_blank" href="{{ url_prefix }}/docs/intent-recognition/#snips-nlu">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <ul>
                            <li>Engine: <tt>{{ maybe_read_path(profile, "intent.snips.engine_dir") }}</tt> </li>
                            <li>Dataset: <tt>{{ maybe_read_path(profile, "intent.snips.dataset_file") }}</tt> </li>
                        </ul>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-snips-language" class="col-form-label">Language:</label>
                        </div>
                        <div class="col">
                            <input id="intent-snips-language" type="text" class="form-control" placeholder="(profile language)" x-model="profile.intent.snips.language">
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col text-muted">
                            Supported Languages: de, en, es, fr, it, ja, ko, pt_br, pt_pt, zh
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="intent-satellite-siteids" type="text" class="form-control" x-model="profile.intent.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Snips NLU -->

            <!-- Remote -->
            <div x-show="profile.intent.system == 'remote'" :disabled="initialSystems.intent != 'remote'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            POSTs plain text to an HTTP endpoint and receives intent JSON back (<a target="_blank" href="{{ url_prefix }}/docs/intent-recognition/#remote">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="intent-url" class="col-form-label">Rhasspy Text-to-Intent URL</label>
                        <div class="col">
                            <input id="intent-url" type="text" class="form-control" x-model="profile.intent.remote.url" :disabled="profile.intent.system != 'remote'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col text-muted">
                            Example: http://localhost:12101/{{ url_prefix }}/api/text-to-intent
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="intent-train-url" class="col-form-label">Training URL</label>
                        <div class="col">
                            <input id="intent-train-url" type="text" class="form-control" x-model="profile.training.intent.remote.url" :disabled="profile.intent.system != 'remote'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="intent-satellite-siteids" type="text" class="form-control" x-model="profile.intent.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Remote -->

            <!-- Command -->
            <div x-show="profile.intent.system == 'command'" :disabled="initialSystems.intent != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls an external program with text on standard input and expects intent JSON on standard output (<a target="_blank" href="{{ url_prefix }}/docs/intent-recognition/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="intent-program" class="col-form-label">Program</label>
                        <div class="col">
                            <input id="intent-program" type="text" class="form-control" x-model="profile.intent.command.program" :disabled="profile.intent.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="intent-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="intent-arguments" type="text" class="form-control" x-model="profile.intent.command.arguments" :disabled="profile.intent.system != 'command'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="intent-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="intent-satellite-siteids" type="text" class="form-control" x-model="profile.intent.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Hermes -->
            <div x-show="profile.intent.system == 'hermes'" :disabled="initialSystems.intent != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects an external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> to recognize intents (<a target="_blank" href="{{ url_prefix }}/docs/services/#intent-recognition">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

        </div>
    </div>
</div>
<!-- End Intent Recognition -->

<!-- Text to Speech -->
<div class="card" id="tts">
    <div class="card-header bg-dark" id="headingTTS">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-paper-plane"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.text_to_speech.system == 'dummy', 'btn-success': profile.text_to_speech.system != 'dummy' }" data-toggle="collapse" data-target="#tts-collapse" aria-expanded="true" aria-controls="tts-collapse" :disabled="profile.text_to_speech.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Text to Speech
            </button>
            <select class="ml-2" x-model="profile.text_to_speech.system">
                <option value="dummy">Disabled</option>
                <option value="espeak">Espeak{% if profile.get("text_to_speech.recommended") == "espeak" %} (Recommended){% elif not profile.get("text_to_speech.picotts.compatible") %} (Incompatible){% endif %}</option>
                <option value="picotts">PicoTTS{% if profile.get("text_to_speech.recommended") == "picotts" %} (Recommended){% elif not profile.get("text_to_speech.picotts.compatible") %} (Incompatible){% endif %}</option>
                <option value="nanotts">NanoTTS{% if profile.get("text_to_speech.recommended") == "nanotts" %} (Recommended){% elif not profile.get("text_to_speech.nanotts.compatible") %} (Incompatible){% endif %}</option>
                <option value="flite">Flite{% if profile.get("text_to_speech.recommended") == "flite" %} (Recommended){% elif not profile.get("text_to_speech.flite.compatible") %} (Incompatible){% endif %}</option>
                <option value="marytts">MaryTTS</option>
                <option value="wavenet">Google Wavenet</option>
                <option value="opentts">OpenTTS</option>
                <option value="larynx">Larynx{% if profile.get("text_to_speech.recommended") == "larynx" %} (Recommended){% elif not profile.get("text_to_speech.larynx.compatible") %} (Incompatible){% endif %}</option>
                <option value="remote">Remote HTTP</option>
                <option value="command">Local Command</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.text_to_speech.system != initialSystems.tts">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
        </h5>
    </div>
    <div id="tts-collapse" class="collapse hide" aria-labelledby="headingTTS" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.text_to_speech.system != initialSystems.tts">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- Espeak -->
            <div x-show="profile.text_to_speech.system == 'espeak'" :disabled="initialSystems.tts != 'espeak'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses <a href="http://espeak.sourceforge.net">eSpeak</a> to speak sentences. Sounds robotic, but supports many languages and locales (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#espeak">Documentation</a>).
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-espeak-voice">Voice:</label>
                        </div>
                        <div class="col">
                            <input id="tts-espeak-voice" x-model="profile.text_to_speech.espeak.voice" type="text" class="form-control" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-espeak-voices">Available Voices:</label>
                        </div>
                        <div class="col">
                            <select id="tts-espeak-voices" x-model="profile.text_to_speech.espeak.voice" class="form-control">
                                <option value="" selected>Default Voice</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshVoices('espeak')" class="btn btn-primary form-control" title="Refresh espeak voices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('espeak')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-espeak-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-espeak-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-espeak-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.espeak.volume" :disabled="profile.text_to_speech.system != 'espeak'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Espeak -->

            <!-- PicoTTS -->
            <div x-show="profile.text_to_speech.system == 'picotts'" :disabled="initialSystems.tts != 'picotts'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses SVOX's <a href="https://en.wikipedia.org/wiki/SVOX">picotts</a> to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#picotts">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-picotts-voice" class="col-form-label">Language:</label>
                        <div class="col">
                            <input id="tts-picotts-voice" type="text" class="form-control" x-model="profile.text_to_speech.picotts.language" :disabled="profile.text_to_speech.system != 'picotts'" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-picotts-languages">Available Languages:</label>
                        </div>
                        <div class="col">
                            <select id="tts-picotts-languages" x-model="profile.text_to_speech.picotts.language" class="form-control">
                                <option value="en-US">en-US</option>
                                <option value="en-GB">en-GB</option>
                                <option value="de-DE">de-DE</option>
                                <option value="es-ES">es-ES</option>
                                <option value="fr-FR">fr-FR</option>
                                <option value="it-IT">it-IT</option>
                            </select>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('picotts')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-picotts-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-picotts-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-picotts-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.picotts.volume" :disabled="profile.text_to_speech.system != 'picotts'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End PicoTTS -->

            <!-- NanoTTS -->
            <div x-show="profile.text_to_speech.system == 'nanotts'" :disabled="initialSystems.tts != 'nanotts'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses an <a href="https://github.com/gmn/nanotts">improved fork</a> of picoTTS to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#nanotts">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-nanotts-voice" class="col-form-label">Language:</label>
                        <div class="col">
                            <input id="tts-nanotts-voice" type="text" class="form-control" x-model="profile.text_to_speech.nanotts.language" :disabled="profile.text_to_speech.system != 'nanotts'" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-nanotts-languages">Available Languages:</label>
                        </div>
                        <div class="col">
                            <select id="tts-nanotts-languages" x-model="profile.text_to_speech.nanotts.language" class="form-control">
                                <option value="en-US">en-US</option>
                                <option value="en-GB">en-GB</option>
                                <option value="de-DE">de-DE</option>
                                <option value="es-ES">es-ES</option>
                                <option value="fr-FR">fr-FR</option>
                                <option value="it-IT">it-IT</option>
                            </select>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('nanotts')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-nanotts-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-nanotts-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-nanotts-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.nanotts.volume" :disabled="profile.text_to_speech.system != 'nanotts'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End NanoTTS -->

            <!-- Flite -->
            <div x-show="profile.text_to_speech.system == 'flite'" :disabled="initialSystems.tts != 'flite'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses FestVox's <a href="http://www.festvox.org/flite">flite</a> to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#flite">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-flite-voice">Voice:</label>
                        </div>
                        <div class="col">
                            <input id="tts-flite-voice" x-model="profile.text_to_speech.flite.voice" type="text" class="form-control" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row mt-2">
                        <div class="col-xs-auto">
                            <label for="tts-flite-voices">Available Voices:</label>
                        </div>
                        <div class="col">
                            <select id="tts-flite-voices" x-model="profile.text_to_speech.flite.voice" class="form-control">
                                <option value="" selected>Default Voice</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshVoices('flite')" class="btn btn-primary form-control" title="Refresh flite voices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('flite')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-flite-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-flite-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-flite-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.flite.volume" :disabled="profile.text_to_speech.system != 'flite'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Flite -->

            <!-- MaryTTS -->
            <div x-show="profile.text_to_speech.system == 'marytts'" :disabled="initialSystems.tts != 'marytts'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses a remote <a href="http://mary.dfki.de/">MaryTTS</a> web server to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#marytts">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-row">
                    <p class="alert alert-info">
                        <strong>Note:</strong> requires an external service (<a href="https://github.com/synesthesiam/docker-marytts">Docker image available</a>)
                    </p>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-marytts-url" class="col-form-label">URL:</label>
                        <div class="col">
                            <input id="tts-marytts-url" type="text" class="form-control" x-model="profile.text_to_speech.marytts.url" :disabled="profile.text_to_speech.system != 'marytts'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-marytts-lang" class="col-form-label">Locale:</label>
                        <div class="col">
                            <input id="tts-marytts-lang" type="text" class="form-control" x-model="profile.text_to_speech.marytts.locale" :disabled="profile.text_to_speech.system != 'marytts'" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-marytts-voice" class="col-form-label">Voice:</label>
                        <div class="col">
                            <input id="tts-marytts-voice" type="text" class="form-control" x-model="profile.text_to_speech.marytts.voice" :disabled="profile.text_to_speech.system != 'marytts'" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-marytts-voices">Available Voices:</label>
                        </div>
                        <div class="col">
                            <select id="tts-marytts-voices" x-model="profile.text_to_speech.marytts.voice" class="form-control">
                                <option value="" selected>Default Voice</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshVoices('marytts')" class="btn btn-primary form-control" title="Refresh marytts voices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('marytts', true)">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-marytts-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-marytts-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-marytts-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.marytts.volume" :disabled="profile.text_to_speech.system != 'marytts'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End MaryTTS -->

            <!-- Wavenet -->
            <div x-show="profile.text_to_speech.system == 'wavenet'" :disabled="initialSystems.tts != 'wavenet'">
                <div class="form-group">
                    <div class="form-row">
                        Uses <a href="https://cloud.google.com/text-to-speech/docs/wavenet">Google's WaveNet</a> to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#wavenet">Documentation</a>)
                    </div>
                </div>
                <div class="form-row">
                    <p class="alert alert-info">
                        <strong>Note:</strong> requires an internet connection and <a href="https://cloud.google.com/text-to-speech/docs/reference/libraries#setting_up_authentication">a Google account</a>
                    </p>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="tts-wavenet-voices" class="col-form-label">Voice:</label>
                        </div>
                        <div class="col">
                            <select id="tts-wavenet-voices" x-model="profile.text_to_speech.wavenet.voice" class="form-control">
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshVoices('wavenet')" class="btn btn-primary form-control" title="Refresh wavenet voices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('wavenet')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-wavenet-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="wavenet-samplerate" class="col-form-label">Sample Rate</label>
                        </div>
                        <div class="col">
                            <select class="form-control" id="wavenet-samplerate" :disabled="profile.text_to_speech.system != 'wavenet'" x-model="profile.text_to_speech.wavenet.sample_rate">
                                <option value="8000">8000</option>
                                <option value="11025">11025</option>
                                <option value="16000">16000</option>
                                <option value="22050">22050</option>
                                <option value="44100">44100</option>
                            </select>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col text-muted">
                            <ul>
                                <li>Credentials: <tt>{{ maybe_read_path(profile, "text_to_speech.wavenet.credentials_json") }}</tt></li>
                                <li>WAV cache: <tt>{{ maybe_read_path(profile, "text_to_speech.wavenet.cache_dir") }}</tt></li>
                            </ul>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-wavenet-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-wavenet-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.wavenet.volume" :disabled="profile.text_to_speech.system != 'wavenet'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Wavenet -->

            <!-- OpenTTS -->
            <div x-show="profile.text_to_speech.system == 'opentts'" :disabled="initialSystems.tts != 'opentts'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses a remote <a href="https://github.com/synesthesiam/opentts">OpenTTS</a> web server to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#opentts">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-row">
                    <p class="alert alert-info">
                        <strong>Note:</strong> requires an external service (<a href="https://github.com/synesthesiam/opentts">Docker image available</a>)
                    </p>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-opentts-url" class="col-form-label">URL:</label>
                        <div class="col">
                            <input id="tts-opentts-url" type="text" class="form-control" x-model="profile.text_to_speech.opentts.url" :disabled="profile.text_to_speech.system != 'opentts'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-opentts-voice" class="col-form-label">Voice:</label>
                        <div class="col">
                            <input id="tts-opentts-voice" type="text" class="form-control" x-model="profile.text_to_speech.opentts.voice" :disabled="profile.text_to_speech.system != 'opentts'" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-opentts-voices">Available Voices:</label>
                        </div>
                        <div class="col">
                            <select id="tts-opentts-voices" x-model="profile.text_to_speech.opentts.voice" class="form-control">
                                <option value="nanotts:en-GB" selected>Default Voice</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshVoices('opentts')" class="btn btn-primary form-control" title="Refresh OpentTTS voices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('opentts')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-opentts-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-opentts-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-opentts-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.opentts.volume" :disabled="profile.text_to_speech.system != 'opentts'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End OpenTTS -->

            <!-- Larynx -->
            <div x-show="profile.text_to_speech.system == 'larynx'" :disabled="initialSystems.tts != 'larynx'">

                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Uses <a href="https://github.com/rhasspy/larynx">Larynx</a> to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#larynx">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-larynx-voice" class="col-form-label">Voice:</label>
                        <div class="col">
                            <input id="tts-larynx-voice" type="text" class="form-control" x-model="profile.text_to_speech.larynx.default_voice" :disabled="profile.text_to_speech.system != 'larynx'" placeholder="default">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-larynx-voices">Available Voices:</label>
                        </div>
                        <div class="col">
                            <select id="tts-larynx-voices" x-model="profile.text_to_speech.larynx.default_voice" class="form-control">
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshVoices('larynx')" class="btn btn-primary form-control" title="Refresh Larynx voices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="tts-larynx-vocoder-quality">Vocoder Quality:</label>
                        </div>
                        <div class="col">
                            <select id="tts-larynx-vocoder-quality" x-model="profile.text_to_speech.larynx.vocoder" class="form-control">
                                <option value="universal_large">High Quality</option>
                                <option value="vctk_medium">Medium Quality</option>
                                <option value="vctk_small">Low Quality</option>
                            </select>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <form onsubmit="speak('larynx')">
                        <div class="form-row">
                            <div class="col-xs-auto">
                                <button type="submit" title="Speak a sentence using text to speech" class="btn btn-info">
                                    <i class="fas fa-inverse fa-paper-plane"></i>
                                    Speak
                                </button>
                            </div>
                            <div class="col">
                                <input type="text" id="tts-larynx-text" class="form-control ml-1" placeholder="Text to speak">
                            </div>
                        </div>
                    </form>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-larynx-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-larynx-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.larynx.volume" :disabled="profile.text_to_speech.system != 'larynx'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Larynx -->

            <!-- Remote -->
            <div x-show="profile.text_to_speech.system == 'remote'" :disabled="initialSystems.tts != 'remote'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            POSTs text to a remote HTTP endpoint and plays received WAV audio (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#remote">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-url" class="col-form-label">Rhasspy Text-to-Speech URL</label>
                        <div class="col">
                            <input id="tts-url" type="text" class="form-control" x-model="profile.text_to_speech.remote.url" :disabled="profile.text_to_speech.system != 'remote'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col text-muted">
                            Example: http://localhost:12101/{{ url_prefix }}/api/text-to-speech
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Remote -->

            <!-- Command -->
            <div x-show="profile.text_to_speech.system == 'command'" :disabled="initialSystems.tts != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls an external program with text on standard input and plays WAV audio from standard output (<a target="_blank" href="{{ url_prefix }}/docs/text-to-speech/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-say-program" class="col-form-label">Say Program</label>
                        <div class="col">
                            <input id="tts-say-program" type="text" class="form-control" x-model="profile.text_to_speech.command.say_program" :disabled="profile.text_to_speech.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-say-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="tts-say-arguments" type="text" class="form-control" x-model="profile.text_to_speech.command.say_arguments" :disabled="profile.text_to_speech.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-command-language" class="col-form-label">Default Language</label>
                        <div class="col">
                            <input id="tts-command-language" type="text" class="form-control" x-model="profile.text_to_speech.command.language" :disabled="profile.text_to_speech.system != 'command'">
                        </div>
                    </div>
                </div>
                <hr>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-voices-program" class="col-form-label">Voices Program</label>
                        <div class="col">
                            <input id="tts-voices-program" type="text" class="form-control" x-model="profile.text_to_speech.command.voices_program" :disabled="profile.text_to_speech.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-voices-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="tts-voices-arguments" type="text" class="form-control" x-model="profile.text_to_speech.command.voices_arguments" :disabled="profile.text_to_speech.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-command-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="tts-command-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.text_to_speech.command.volume" :disabled="profile.text_to_speech.system != 'command'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Hermes -->
            <div x-show="profile.text_to_speech.system == 'hermes'" :disabled="initialSystems.tts != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects an external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> to speak sentences (<a target="_blank" href="{{ url_prefix }}/docs/services/#text-to-speech">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

            <!-- Satellite siteIds -->
            <div x-show="profile.text_to_speech.system != 'dummy'">
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="tts-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="tts-satellite-siteids" type="text" class="form-control" x-model="profile.text_to_speech.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Satellite siteIds -->

        </div>
    </div>
</div>
<!-- End Audio Recording -->

<!-- Audio Playing -->
<div class="card" id="sounds">
    <div class="card-header bg-dark" id="headingSounds">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-volume-up"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.sounds.system == 'dummy', 'btn-success': profile.sounds.system != 'dummy' }" data-toggle="collapse" data-target="#sounds-collapse" aria-expanded="true" aria-controls="sounds-collapse" :disabled="profile.sounds.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Audio Playing
            </button>
            <select class="ml-2" x-model="profile.sounds.system">
                <option value="dummy">Disabled</option>
                <option value="aplay">aplay{% if profile.get("sounds.recommended") == "aplay" %} (Recommended){% endif %}</option>
                <option value="remote">Remote HTTP</option>
                <option value="command">Local Command</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.sounds.system != initialSystems.sounds">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
        </h5>
    </div>
    <div id="sounds-collapse" class="collapse hide" aria-labelledby="headingSounds" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.sounds.system != initialSystems.sounds">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- aplay -->
            <div x-show="profile.sounds.system == 'aplay'" :disabled="initialSystems.sounds != 'aplay'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Plays WAV files on the local device by calling the <tt>aplay</tt> command (<a target="_blank" href="{{ url_prefix }}/docs/audio-output/#alsa">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="sounds-aplay-device">Device:</label>
                        </div>
                        <div class="col">
                            <input id="sounds-aplay-device" x-model="profile.sounds.aplay.device" type="text" class="form-control">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-xs-auto">
                            <label for="sounds-aplay-devices">Available Devices:</label>
                        </div>
                        <div class="col">
                            <select id="sounds-aplay-devices" x-model="profile.sounds.aplay.device" class="form-control">
                                <option value="" selected>Default Device</option>
                            </select>
                        </div>
                        <div class="col-xs-auto">
                            <button onclick="refreshOutputDevices('aplay')" class="btn btn-primary form-control" placeholder="Refresh aplay devices">Refresh</button>
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="sounds-aplay-volume" class="col-form-label">Volume</label>
                        <div class="col-sm-auto">
                            <input id="sounds-aplay-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.sounds.aplay.volume" :disabled="profile.sounds.system != 'aplay'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End aplay -->

            <!-- Remote -->
            <div x-show="profile.sounds.system == 'remote'" :disabled="initialSystems.sounds != 'remote'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            POSTs WAV audio to a remote HTTP endpoint (<a target="_blank" href="{{ url_prefix }}/docs/audio-output/#remote">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="tts-url" class="col-form-label">Audio Output URL</label>
                        <div class="col">
                            <input id="tts-url" type="text" class="form-control" x-model="profile.sounds.remote.url" :disabled="profile.sounds.system != 'remote'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Remote -->

            <!-- Command -->
            <div x-show="profile.sounds.system == 'command'" :disabled="initialSystems.sounds != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls an external program with WAV audio on standard input (<a target="_blank" href="{{ url_prefix }}/docs/audio-output/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="sounds-program" class="col-form-label">Program</label>
                        <div class="col">
                            <input id="sounds-program" type="text" class="form-control" x-model="profile.sounds.command.play_program" :disabled="profile.sounds.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="sounds-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="sounds-arguments" type="text" class="form-control" x-model="profile.sounds.command.play_arguments" :disabled="profile.sounds.system != 'command'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Hermes -->
            <div x-show="profile.sounds.system == 'hermes'" :disabled="initialSystems.sounds != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects an external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> to play audio (<a target="_blank" href="{{ url_prefix }}/docs/services/#audio-output">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

        </div>
    </div>
</div>
<!-- End Audio Recording -->

<!-- Dialogue Management -->
<div class="card" id="dialogue">
    <div class="card-header bg-dark" id="headingDialogue">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-tasks"></i>
            <button class="btn" x-bind:class="{ 'btn-danger': profile.dialogue.system == 'dummy', 'btn-success': profile.dialogue.system != 'dummy' }" data-toggle="collapse" data-target="#dialogue-collapse" aria-expanded="true" aria-controls="dialogue-collapse" :disabled="profile.dialogue.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Dialogue Management
            </button>
            <select class="ml-2" x-model="profile.dialogue.system">
                <option value="dummy">Disabled</option>
                <option value="rhasspy">Rhasspy{% if profile.get("dialogue.recommended") == "rhasspy" %} (Recommended){% endif %}</option>
                <option value="hermes">Hermes MQTT</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.dialogue.system != initialSystems.dialogue">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
        </h5>
    </div>
    <div id="dialogue-collapse" class="collapse hide" aria-labelledby="headingDialogue" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.dialogue.system != initialSystems.dialogue">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- Rhasspy -->
            <div x-show="profile.dialogue.system == 'rhasspy'" :disabled="initialSystems.dialogue != 'rhasspy'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Makes Rhasspy behave like a typical voice assistant, automatically listening for voice commands after hotword detections and recognizing intents from them (<a target="_blank" href="{{ url_prefix }}/docs/services/#dialogue-manager">Documentation</a>)
                        </p>
                    </div>
                    <div class="form-row">
                        <p>
                            Uses <a href="https://github.com/rhasspy/rhasspy-dialogue-hermes">rhasspy-dialogue-hermes</a> service
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="dialogue-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="dialogue-satellite-siteids" type="text" class="form-control" x-model="profile.dialogue.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Rhasspy -->

            <!-- Hermes -->
            <div x-show="profile.dialogue.system == 'hermes'" :disabled="initialSystems.dialogue != 'hermes'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Expects a custom external service that supports the <a href="https://docs.snips.ai/reference/hermes">Hermes Protocol</a> to do something with hotword detections, etc. (<a target="_blank" href="{{ url_prefix }}/docs/services/#dialogue-manager">Documentation</a>)
                        </p>
                    </div>
                </div>
            </div>
            <!-- End Hermes -->

        </div>
    </div>
</div>
<!-- End Audio Playing -->

<!-- Intent Handling -->
<div class="card" id="handle">
    <div class="card-header bg-dark" id="headingHandle">
        <h5 class="mb-0">
            <i class="fas fa-inverse fa-bolt"></i>
            <button class="btn" x-bind:class="{ 'btn-outline-light': profile.handle.system == 'dummy', 'btn-success': profile.handle.system != 'dummy' }" data-toggle="collapse" data-target="#handle-collapse" aria-expanded="true" aria-controls="handle-collapse" :disabled="profile.handle.system == 'dummy'">
                <i class="fas fa-sort-down"></i>Intent Handling
            </button>
            <select class="ml-2" x-model="profile.handle.system">
                <option value="dummy">Disabled</option>
                <option value="hass">Home Assistant</option>
                <option value="remote">Remote HTTP</option>
                <option value="command">Local Command</option>
            </select>

            <span class="fa-stack ml-2" x-show="profile.handle.system != initialSystems.handle">
                <i class="fas fa-circle fa-stack-2x text-danger"></i>
                <i class="fas fa-power-off fa-stack-1x fa-inverse" title="Restart is required"></i>
            </span>
        </h5>
    </div>
    <div id="handle-collapse" class="collapse hide" aria-labelledby="headingHandle" data-parent="#accordion">
        <div class="card-body">
            <div x-show="profile.handle.system != initialSystems.handle">
                <div class="mb-3">
                    <button onclick="saveProfile()" class="btn btn-danger" title="Save all settings and restart Rhasspy">
                        <i class="fas fa-power-off fa-inverse mr-2"></i>
                        Save and Restart Required
                    </button>
                </div>
            </div>

            <!-- Home Assistant -->
            <div x-show="profile.handle.system == 'hass'" :disabled="initialSystems.handle != 'hass'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Sends intents or events directly to <a href="https://www.home-assistant.io">Home Assistant</a> or <a href="https://www.home-assistant.io/hassio/">Hass.io</a> (<a target="_blank" href="{{ url_prefix }}/docs/intent-handling/#home-assistant">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="hass-url" class="col-form-label">Hass URL</label>
                        <div class="col">
                            <input id="hass-url" type="text" class="form-control" x-model="profile.home_assistant.url"
                                   :disabled="profile.handle.system != 'hass'">
                        </div>
                        <div class="col text-muted">
                            Address of your Home Assistant server
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="hass-token" class="col-form-label">Access Token</label>
                        <div class="col">
                            <input id="hass-token" type="password" class="form-control" x-model="profile.home_assistant.access_token"
                                   :disabled="profile.handle.system != 'hass'">
                        </div>
                        <div class="col text-muted">
                            Long-lived access token (automatically filled in Hass.IO)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="hass-password" class="col-form-label">API Password</label>
                        <div class="col">
                            <input id="hass-password" type="password" class="form-control" x-model="profile.home_assistant.api_password"
                                   :disabled="profile.handle.system != 'hass'">
                        </div>
                        <div class="col text-muted">
                            Home Assistant password (deprecated)
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <div class="form-check">
                            <input class="form-check-input" type="radio" id="hass-handle-type-event" value="event" x-model="profile.home_assistant.handle_type" :disabled="profile.handle.system != 'hass'">
                            <label class="form-check-label" for="hass-handle-type-event">
                                Send <strong>events</strong> to Home Assistant (<tt>/api/events</tt>)
                            </label>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col">
                            <p class="text-muted">
                                Events will be named <tt x-html="profile.home_assistant.event_type_format.replace('{0}', 'INTENT_NAME')"></tt>
                            </p>
                        </div>
                    </div>
                    <div class="form-row mt-2">
                        <div class="form-check">
                            <input class="form-check-input" type="radio" id="hass-handle-type-intent" value="intent" x-model="profile.home_assistant.handle_type" :disabled="profile.handle.system != 'hass'">
                            <label class="form-check-label" for="hass-handle-type-intent">
                                Send <strong>intents</strong> to Home Assistant (<tt>/api/intent/handle</tt>)
                            </label>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col">
                            <p class="text-muted">
                                Requires the <tt>intent</tt> component and <a href="https://www.home-assistant.io/integrations/intent_script">intent scripts</a> in your <tt>configuration.yaml</tt>
                            </p>
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Home Assistant -->

            <!-- Remote -->
            <div x-show="profile.handle.system == 'remote'" :disabled="initialSystems.handle != 'remote'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            POSTs intent JSON to a remote HTTP endpoint (<a target="_blank" href="{{ url_prefix }}/docs/intent-handling/#remote-server">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="remote-handle-url" class="col-form-label">Remote URL</label>
                        <div class="col">
                            <input id="remote-handle-url" type="text" class="form-control" x-model="profile.handle.remote.url" :disabled="profile.handle.system != 'remote'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Remote -->

            <!-- Command -->
            <div x-show="profile.handle.system == 'command'" :disabled="initialSystems.handle != 'command'">
                <div class="form-group">
                    <div class="form-row">
                        <p>
                            Calls a custom external program with intent JSON on standard input (<a target="_blank" href="{{ url_prefix }}/docs/intent-handling/#command">Documentation</a>)
                        </p>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="handle-program" class="col-form-label">Program</label>
                        <div class="col">
                            <input id="handle-program" type="text" class="form-control" x-model="profile.handle.command.program" :disabled="profile.handle.system != 'command'">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="form-row">
                        <label for="handle-arguments" class="col-form-label">Arguments</label>
                        <div class="col">
                            <input id="handle-arguments" type="text" class="form-control" x-model="profile.handle.command.arguments" :disabled="profile.handle.system != 'command'">
                        </div>
                    </div>
                </div>
            </div>
            <!-- End Command -->

            <!-- Satellite siteIds -->
            <div x-show="!['dummy', 'hermes'].includes(profile.handle.system)">
                <div class="form-group">
                    <div class="form-row">
                        <div class="col-auto">
                            <label for="handle-satellite-siteids" class="col-form-label">Satellite siteIds:</label>
                        </div>
                        <div class="col">
                            <input id="handle-satellite-siteids" type="text" class="form-control" x-model="profile.handle.satellite_site_ids">
                        </div>
                        <div class="col-auto text-muted">
                            (comma-separated)
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- End Intent Handling -->



<button onclick="saveProfile()" class="btn btn-primary mt-3" title="Save all settings and restart Rhasspy">Save Settings</button>

<!-- Sounds -->
<div class="card mt-3">
    <div class="card-header bg-success text-light">
        <h5>Sounds</h5>
    </div>
    <div class="card-body">
        <div class="form-group">
            <div class="form-row">
                <p>
                    WAV files to play when Rhasspy wakes up and is finished recording a voice command.
                </p>
            </div>
            <div class="form-row">
                <p class="alert alert-info">
                    <strong>Note:</strong> dialogue management must be set to "Rhasspy" to hear these sounds
                </p>
            </div>
            <div class="form-row">
                <p class="text-muted">
                    Use <tt>${RHASSPY_PROFILE_DIR}</tt> environment variable for your profile directory.
                </p>
            </div>
        </div>
        <div class="form-group">
            <div class="form-row">
                <label for="sounds-wake" class="col-form-label">Wake WAV</label>
                <div class="col">
                    <input id="sounds-wake" type="text" class="form-control" x-model="profile.sounds.wake">
                </div>
                <div class="col-auto text-muted">
                    (empty to disable)
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="form-row">
                <label for="sounds-recorded" class="col-form-label">Recorded WAV</label>
                <div class="col">
                    <input id="sounds-recorded" type="text" class="form-control" x-model="profile.sounds.recorded">
                </div>
                <div class="col-auto text-muted">
                    (empty to disable)
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="form-row">
                <label for="sounds-error" class="col-form-label">Error WAV</label>
                <div class="col">
                    <input id="sounds-error" type="text" class="form-control" x-model="profile.sounds.error">
                </div>
                <div class="col-auto text-muted">
                    (empty to disable)
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="form-row">
                <label for="dialogue-volume" class="col-form-label">Volume</label>
                <div class="col-sm-auto">
                    <input id="dialogue-volume" type="number" min="0" max="1" step="0.05" class="form-control" x-model="profile.dialogue.volume">
                </div>
            </div>
        </div>
    </div>
</div>
<!-- End Sounds -->

<!-- SSL -->
<div class="card mt-3" id="ssl">
    <div class="card-header bg-info text-light">
        <h5>Certificates</h5>
    </div>
    <div class="card-body">
        <div class="form-group">
            <div class="form-row">
                <p>
                    Files needed for using HTTPS with your Rhasspy server or Home Assistant
                </p>
            </div>
            <div class="form-row">
                <p class="alert alert-info">
                    <strong>Note:</strong> all paths should be absolute
                </p>
            </div>
            <div class="form-row">
                <p class="text-muted">
                    Use <tt>${RHASSPY_PROFILE_DIR}</tt> environment variable for your profile directory.
                </p>
            </div>
        </div>
        <div class="form-group">
            <div class="form-row">
                <div class="col-auto">
                    <label for="certfile" class="col-form-label col">Certificate Path:</label>
                </div>
                <div class="col">
                    <input id="certfile" type="text" class="form-control" x-model="profile.home_assistant.pem_file" placeholder="certfile">
                </div>
                <div class="col-auto">
                    <p class="muted"><a href="https://docs.python.org/3/library/ssl.html#combined-key-and-certificate">PEM certificate file</a> (required)</p>
                </div>
            </div>
        </div>
        <div class="form-group">
            <div class="form-row">
                <div class="col-auto">
                    <label for="keyfile" class="col-form-label col">Key Path:</label>
                </div>
                <div class="col">
                    <input id="keyfile" type="text" class="form-control" x-model="profile.home_assistant.key_file" placeholder="keyfile">
                </div>
                <div class="col-auto">
                    <p class="muted"><a href="https://docs.python.org/3/library/ssl.html#ssl-certificates">Private key file</a> (optional)</p>
                </div>
            </div>
        </div>
    </div>
</div>
<!-- End SSL -->

<button onclick="saveProfile()" class="btn btn-primary mt-3 mb-3" title="Save all settings and restart Rhasspy">Save Settings</button>


{% endblock %}

{% block script %}
<script type="text/javascript">
 var initialSystems = {};

 // POST to /api/profile to save and then restart Rhasspy
 function saveProfile(reload, confirmRestart) {
     reload = (reload === undefined) ? false : reload;
     confirmRestart = (confirmRestart === undefined) ? true : confirmRestart;
     rhasspy.postBusy('Saving profile',
                      '/api/profile',
                      JSON.stringify(rhasspy.profile),
                      false)
            .done(function() {
                var doRestart = true;
                if (confirmRestart) {
                    doRestart = window.confirm("Settings saved. Restart Rhasspy?");
                }

                if (doRestart) {
                    rhasspy.restart().done(function() {
                        if (reload) {
                            window.location.reload();
                        }
                    });
                } else {
                    rhasspy.hideBusy();
                }
            });
 }

 // Load available audio input devices
 function refreshInputDevices(micSystem, suppressMessage = false) {
     var selectId = '#microphone-' + micSystem + '-devices';
     var message = (suppressMessage) ? '' : 'Refreshing microphones';
     $(selectId + ' option:not(:first)').remove();

     rhasspy.getBusy(message,
                     '/api/microphones')
            .done((r) => {
                Object.entries(r).forEach((kv) => {
                    var selected = (kv[0] == rhasspy.profile.microphone[micSystem].device) ? ' selected' : '';
                    $(selectId)
                        .append('<option value="' + kv[0] + '"' + selected + '>' + kv[1] + ' (' + kv[0] + ')</option>');
                });
            });
 }

 // Test available audio input devices
 function testInputDevices(micSystem) {
     var selectId = '#microphone-' + micSystem + '-devices';
     $(selectId + ' option:not(:first)').remove();

     rhasspy.getBusy('Testing microphones',
                     '/api/test-microphones')
            .done((r) => {
                Object.entries(r).forEach((kv) => {
                    $(selectId)
                        .append('<option value="' + kv[0] + '">' + kv[1] + ' (' + kv[0] + ')</option>');
                });
            });
 }

 // Load available audio output devices
 function refreshOutputDevices(soundSystem, suppressMessage = false) {
     var selectId = '#sounds-' + soundSystem + '-devices';
     var message = (suppressMessage) ? '' : 'Refreshing speakers';
     $(selectId + ' option:not(:first)').remove();

     rhasspy.getBusy(message,
                     '/api/speakers')
            .done((r) => {
                Object.entries(r).forEach((kv) => {
                    var selected = (kv[0] == rhasspy.profile.sounds[soundSystem].device) ? ' selected' : '';
                    $(selectId)
                        .append('<option value="' + kv[0] + '"' + selected + '>' + kv[1] + ' (' + kv[0] + ')</option>');
                });
            });
 }

 // Load available hot words
 function refreshHotwords(wakeSystem, suppressMessage = false) {
     if (wakeSystem == 'raven') {
         return;
     }

     var selectId = '#wake-' + wakeSystem + '-hotwords';
     var message = (suppressMessage) ? '' : 'Refreshing hotwords';
     $(selectId + ' option').remove();

     rhasspy.getBusy(message,
                     '/api/wake-words')
            .done((r) => {
                r.forEach((hotword) => {
                    var selected = (hotword.modelId == rhasspy.profile.wake[wakeSystem].modelId) ? ' selected' : '';
                    $(selectId)
                        .append('<option value="' + hotword.modelId + '"' + selected + '>' + hotword.modelWords + ' (' + hotword.modelId + ')</option>');
                });
            });
 }

 // Delete a Raven hot word
 function deleteHotword(wakewordId, suppressMessage = false) {
     var message = (suppressMessage) ? '' : 'Deleting ' + wakewordId;

     if (window.confirm('Really delete ' + wakewordId + '?')) {
         rhasspy.postBusy(message,
                          '/api/delete-wake-word',
                          wakewordId)
                .done((r) => {
                    if (wakewordId in rhasspy.profile.wake.raven.keywords) {
                        delete rhasspy.profile.wake.raven.keywords[wakewordId];
                    }

                    saveProfile(true, false);
                });
     }
 }

 // Load available TTS voices
 function refreshVoices(ttsSystem, suppressMessage = false) {
     var selectId = '#tts-' + ttsSystem + '-voices';
     var message = (suppressMessage) ? '' : 'Refreshing voices';
     $(selectId + ' option:not(:first)').remove();

     rhasspy.getBusy(message,
                     '/api/tts-voices')
            .done((r) => {
                r.forEach((voice) => {
                    var description = voice.voiceId;
                    var selected = (voice.voiceId == rhasspy.profile.text_to_speech[ttsSystem].voice) ? ' selected' : '';
                    if (voice.description) {
                        description += ' (' + voice.description + ')';
                    }
                    $(selectId)
                        .append('<option value="' + voice.voiceId + '"' + selected + '>' + description + '</option>');
                });
            });
 }

 // Record an example for Rhasspy Raven
 function ravenRecord(button, wakewordId, i, dirname, showRestart) {
     showRestart = (showRestart === undefined) ? false : showRestart;

     if (wakewordId.length == 0) {
         wakewordId = $('#wake-raven-keyword-name').val();
     }

     if (wakewordId.length == 0) {
         alert('No keyword name');
         return;
     }

     var filename = dirname + '/' + wakewordId + '/example-' + i + '.wav'

     var message = 'Speak wake word (' + filename + ')';
     var missing = $('#raven-missing-' + i);

     rhasspy.postBusy(message,
                      '/api/record-wake-example?savePath=' + filename)
            .done((r) => {
                // Show checkmark
                $('i', button).show();

                if (showRestart) {
                    $('#wake-raven-restart-required').show();
                }
            });
 }

 function enableRavenKeyword(keywordName, enabled) {
     if (!(keywordName in rhasspy.profile.wake.raven.keywords)) {
         rhasspy.profile.wake.raven.keywords[keywordName] = {};
     }
     rhasspy.profile.wake.raven.keywords[keywordName].enabled = enabled;
 }

 function saveRavenKeyword() {
     var keywordName = $('#wake-raven-keyword-name').val();
     if (keywordName.length == 0) {
         alert('No keyword name');
         return;
     }

     enableRavenKeyword(keywordName, true);

     // Examples should already be saved
     saveProfile(true, false);
 }

 function playRavenExample(wakewordId, i, dirname) {
     if (wakewordId.length == 0) {
         wakewordId = $('#wake-raven-keyword-name').val();
     }

     var wavPath = dirname + '/' + wakewordId + '/example-' + i + '.wav';
     rhasspy.postBusy('Playing ' + wavPath, '/api/play-wav', wavPath);
 }

 function isSpeechCompatible() {
     var speechSystem = rhasspy.profile.speech_to_text.system;
     return rhasspy.profile.speech_to_text[speechSystem].compatible;
 }

 function isWakeCompatible() {
     var wakeSystem = rhasspy.profile.wake.system;
     return rhasspy.profile.wake[wakeSystem].compatible;
 }

 var energies = null;
 function toggleAudioStatistics() {
     if ($('#toggle-audio-statistics').prop('checked')) {
         // Enable audio stats
         payload = "on";
     } else {
         // Disable audio stats
         payload = "off";
     }

     $.post({
         url: '{{ url_prefix }}/api/audio-summaries',
         data: payload
     });
 }

 function updateEnergies() {
     // Update text boxes with recent audio summary info
     if (energies != null) {
         $('#audio-current-energy').val(energies.current_energy);
         $('#audio-max-energy').val(energies.max_energy);
         $('#audio-min-energy').val(energies.min_energy);
         $('#audio-ratio-energy').val(energies.max_current_ratio);
     }
 }

 function refreshSelects() {
     if ($('#tts-' + rhasspy.profile.text_to_speech.system + '-voices').length) {
         refreshVoices(rhasspy.profile.text_to_speech.system, true);
     }

     if ($('#wake-' + rhasspy.profile.wake.system + '-hotwords').length) {
         refreshHotwords(rhasspy.profile.wake.system, true);
     }

     if ($('#sounds-' + rhasspy.profile.sounds.system + '-devices').length) {
         refreshOutputDevices(rhasspy.profile.sounds.system, true);
     }

     if ($('#microphone-' + rhasspy.profile.microphone.system + '-devices').length) {
         refreshInputDevices(rhasspy.profile.microphone.system, true);
     }
 }

 // POST text to /api/text-to-speech to speak sentence with selected voice
 function speak(textId, langAndVoice) {
     event.preventDefault();
     langAndVoice = (langAndVoice === undefined) ? false : langAndVoice;

     var text = $('#tts-' + textId + '-text').val() || '';
     if (text.length > 0) {
         var voice = $('#tts-' + textId + '-voice').val() || '';
         if (langAndVoice) {
             var lang = $('#tts-' + textId + '-lang').val() || '';
             if (lang.length > 0) {
                 voice = lang + '/' + voice;
             }
         }

         rhasspy.postBusy(text, '/api/text-to-speech?voice=' + voice, text);
     } else {
         alert('No text to speak')
     }

     return false;
 }

 $(document).ready(() => {
     // Highlight selected section from URL
     var hash = $(location).attr('hash') || '';
     if (hash.length > 0) {
         var header = hash + ' .card-header';
         $(header).addClass('bg-primary');
         $(header).removeClass('bg-dark');

         // Expand section
         $(hash + '-collapse').addClass('show');

         // Account for fixed header top
         // See: https://stackoverflow.com/questions/4086107/fixed-page-header-overlaps-in-page-anchors
         var offset = $(':target').offset();
         var scrollTo = offset.top - 70;
         $('html, body').animate({ scrollTop: scrollTo}, 0);
     }

     refreshSelects();

     rhasspy.makeWebSocket(
         '/api/events/audiosummary',
         (socket) => {
             $('#audio-statistics-connecting').hide();
             socket.onmessage = (e) => {
                 energies = JSON.parse(e.data);
             }
         });

     // Update audio energies 2x per second
     setInterval(updateEnergies, 500);

     // Firefox really wants to copy the probability threshold into here for some reason
     $('#wake-raven-keyword-name').val('');
 })

</script>
{% endblock %}
